home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / manageme / tcpdump-.7 / tcpdump- / tcpdump-richard-1.7 / libpcap-0.0 / nametoaddr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-12  |  7.2 KB  |  361 lines

  1. /*
  2.  * Copyright (c) 1990, 1991, 1992, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * Name to id translation routines used by the scanner.
  22.  * These functions are not time critical.
  23.  */
  24.  
  25. #ifndef lint
  26. static char rcsid[] =
  27.     "@(#) $Header: nametoaddr.c,v 1.21 94/06/20 19:07:54 leres Exp $ (LBL)";
  28. #endif
  29.  
  30. #include <sys/param.h>
  31. #include <sys/socket.h>
  32. #include <net/if.h>
  33. #include <netinet/in.h>
  34. #include <netinet/if_ether.h>
  35. #include <arpa/inet.h>
  36.  
  37. #include <ctype.h>
  38. #include <errno.h>
  39. #include <netdb.h>
  40. #include <pcap.h>
  41. #include <pcap-namedb.h>
  42. #include <stdio.h>
  43. #if __STDC__
  44. #include <stdlib.h>
  45. #endif
  46.  
  47. #include "gencode.h"
  48.  
  49. #ifndef __GNUC__
  50. #define inline
  51. #endif
  52.  
  53. #ifndef NTOHL
  54. #define NTOHL(x) (x) = ntohl(x)
  55. #define NTOHS(x) (x) = ntohs(x)
  56. #endif
  57.  
  58. static inline int xdtoi(int);
  59.  
  60. /*
  61.  *  Convert host name to internet address.
  62.  *  Return 0 upon failure.
  63.  */
  64. u_long **
  65. pcap_nametoaddr(const char *name)
  66. {
  67. #ifndef h_addr
  68.     static u_long *hlist[2];
  69. #endif
  70.     u_long **p;
  71.     struct hostent *hp;
  72.  
  73.     if ((hp = gethostbyname(name)) != NULL) {
  74. #ifndef h_addr
  75.         hlist[0] = (u_long *)hp->h_addr;
  76.         NTOHL(hp->h_addr);
  77.         return hlist;
  78. #else
  79.         for (p = (u_long **)hp->h_addr_list; *p; ++p)
  80.             NTOHL(**p);
  81.         return (u_long **)hp->h_addr_list;
  82. #endif
  83.     }
  84.     else
  85.         return 0;
  86. }
  87.  
  88. /*
  89.  *  Convert net name to internet address.
  90.  *  Return 0 upon failure.
  91.  */
  92. u_long
  93. pcap_nametonetaddr(const char *name)
  94. {
  95.     struct netent *np;
  96.  
  97.     if ((np = getnetbyname(name)) != NULL)
  98.         return np->n_net;
  99.     else
  100.         return 0;
  101. }
  102.  
  103. /*
  104.  * Convert a port name to its port and protocol numbers.
  105.  * We assume only TCP or UDP.
  106.  * Return 0 upon failure.
  107.  */
  108. int
  109. pcap_nametoport(const char *name, int *port, int *proto)
  110. {
  111.     struct servent *sp;
  112.     char *other;
  113.  
  114.     sp = getservbyname(name, (char *)0);
  115.     if (sp != NULL) {
  116.         NTOHS(sp->s_port);
  117.         *port = sp->s_port;
  118.         *proto = pcap_nametoproto(sp->s_proto);
  119.         /*
  120.          * We need to check /etc/services for ambiguous entries.
  121.          * If we find the ambiguous entry, and it has the
  122.          * same port number, change the proto to PROTO_UNDEF
  123.          * so both TCP and UDP will be checked.
  124.          */
  125.         if (*proto == IPPROTO_TCP)
  126.             other = "udp";
  127.         else
  128.             other = "tcp";
  129.  
  130.         sp = getservbyname(name, other);
  131.         if (sp != 0) {
  132.             NTOHS(sp->s_port);
  133.             if (*port != sp->s_port)
  134.             {
  135.                 /* Can't handle ambiguous names that refer
  136.                    to different port numbers. */
  137. #ifdef notdef
  138.                 warning("ambiguous port %s in /etc/services",
  139.                     name);
  140. #endif
  141.             }
  142.             *proto = PROTO_UNDEF;
  143.         }
  144.         return 1;
  145.     }
  146. #if defined(ultrix) || defined(__osf__)
  147.     /* Special hack in case NFS isn't in /etc/services */
  148.     if (strcmp(name, "nfs") == 0) {
  149.         *port = 2049;
  150.         *proto = PROTO_UNDEF;
  151.         return 1;
  152.     }
  153. #endif
  154.     return 0;
  155. }
  156.  
  157. int
  158. pcap_nametoproto(const char *str)
  159. {
  160.     struct protoent *p;
  161.  
  162.     p = getprotobyname(str);
  163.     if (p != 0)
  164.         return p->p_proto;
  165.     else
  166.         return PROTO_UNDEF;
  167. }
  168.  
  169. #include "ethertype.h"
  170.  
  171. struct eproto {
  172.     char *s;
  173.     u_short p;
  174. };
  175.  
  176. /* Static data base of ether protocol types. */
  177. struct eproto eproto_db[] = {
  178.     { "pup", ETHERTYPE_PUP },
  179.     { "xns", ETHERTYPE_NS },
  180.     { "ip", ETHERTYPE_IP },
  181.     { "arp", ETHERTYPE_ARP },
  182.     { "rarp", ETHERTYPE_REVARP },
  183.     { "sprite", ETHERTYPE_SPRITE },
  184.     { "mopdl", ETHERTYPE_MOPDL },
  185.     { "moprc", ETHERTYPE_MOPRC },
  186.     { "decnet", ETHERTYPE_DN },
  187.     { "lat", ETHERTYPE_LAT },
  188.     { "lanbridge", ETHERTYPE_LANBRIDGE },
  189.     { "vexp", ETHERTYPE_VEXP },
  190.     { "vprod", ETHERTYPE_VPROD },
  191.     { "atalk", ETHERTYPE_ATALK },
  192.     { "atalkarp", ETHERTYPE_AARP },
  193.     { "loopback", ETHERTYPE_LOOPBACK },
  194.     { "decdts", ETHERTYPE_DECDTS },
  195.     { "decdns", ETHERTYPE_DECDNS },
  196.     { (char *)0, 0 }
  197. };
  198.  
  199. int
  200. pcap_nametoeproto(const char *s)
  201. {
  202.     struct eproto *p = eproto_db;
  203.  
  204.     while (p->s != 0) {
  205.         if (strcmp(p->s, s) == 0)
  206.             return p->p;
  207.         p += 1;
  208.     }
  209.     return PROTO_UNDEF;
  210. }
  211.  
  212. /* Hex digit to integer. */
  213. static inline int
  214. xdtoi(c)
  215.     register int c;
  216. {
  217.     if (isdigit(c))
  218.         return c - '0';
  219.     else if (islower(c))
  220.         return c - 'a' + 10;
  221.     else
  222.         return c - 'A' + 10;
  223. }
  224.  
  225. u_long
  226. __pcap_atoin(const char *s)
  227. {
  228.     u_long addr = 0;
  229.     u_int n;
  230.  
  231.     while (1) {
  232.         n = 0;
  233.         while (*s && *s != '.')
  234.             n = n * 10 + *s++ - '0';
  235.         addr <<= 8;
  236.         addr |= n & 0xff;
  237.         if (*s == '\0')
  238.             return addr;
  239.         ++s;
  240.     }
  241.     /* NOTREACHED */
  242. }
  243.  
  244. u_long
  245. __pcap_atodn(const char *s)
  246. {
  247. #define AREASHIFT 10
  248. #define AREAMASK 0176000
  249. #define NODEMASK 01777
  250.  
  251.     u_long addr = 0;
  252.     u_int node, area;
  253.  
  254.     if (sscanf((char *)s, "%d.%d", &area, &node) != 2)
  255.         bpf_error("malformed decnet address '%s'", s);
  256.  
  257.     addr = (area << AREASHIFT) & AREAMASK;
  258.     addr |= (node & NODEMASK);
  259.  
  260.     return(addr);
  261. }
  262.  
  263. /*
  264.  * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new
  265.  * ethernet address.  Assumes 's' is well formed.
  266.  */
  267. u_char *
  268. pcap_ether_aton(const char *s)
  269. {
  270.     register u_char *ep, *e;
  271.     register u_int d;
  272.  
  273.     e = ep = (u_char *)malloc(6);
  274.  
  275.     while (*s) {
  276.         if (*s == ':')
  277.             s += 1;
  278.         d = xdtoi(*s++);
  279.         if (isxdigit(*s)) {
  280.             d <<= 4;
  281.             d |= xdtoi(*s++);
  282.         }
  283.         *ep++ = d;
  284.     }
  285.  
  286.     return (e);
  287. }
  288.  
  289. #ifndef ETHER_SERVICE
  290. /* Roll our own */
  291. u_char *
  292. pcap_ether_hostton(const char *name)
  293. {
  294.     register struct pcap_etherent *ep;
  295.     register u_char *ap;
  296.     static FILE *fp = NULL;
  297.     static init = 0;
  298.  
  299.     if (!init) {
  300.         fp = fopen(PCAP_ETHERS_FILE, "r");
  301.         ++init;
  302.         if (fp == NULL)
  303.             return (NULL);
  304.     } else if (fp == NULL)
  305.         return (NULL);
  306.     else
  307.         rewind(fp);
  308.     
  309.     while ((ep = pcap_next_etherent(fp)) != NULL) {
  310.         if (strcmp(ep->name, name) == 0) {
  311.             ap = (u_char *)malloc(6);
  312.             if (ap != NULL) {
  313.                 memcpy(ap, ep->addr, 6);
  314.                 return (ap);
  315.             }
  316.             break;
  317.         }
  318.     }
  319.     return (NULL);
  320. }
  321. #else
  322. /* Use the os supplied routines */
  323. u_char *
  324. pcap_ether_hostton(const char *name)
  325. {
  326.     register u_char *ap;
  327.     u_char a[6];
  328. #ifndef sgi
  329.     extern int ether_hostton(char *, struct ether_addr *);
  330. #endif
  331.  
  332.     ap = NULL;
  333.     if (ether_hostton((char*)name, (struct ether_addr *)a) == 0) {
  334.         ap = (u_char *)malloc(6);
  335.         if (ap != NULL)
  336.             memcpy(ap, a, 6);
  337.     }
  338.     return (ap);
  339. }
  340. #endif
  341.  
  342. u_short
  343. __pcap_nametodnaddr(const char *name)
  344. {
  345. #ifdef    DECNETLIB
  346.     struct nodeent *getnodebyname();
  347.     struct nodeent *nep;
  348.     unsigned short res;
  349.  
  350.     nep = getnodebyname(name);
  351.     if (nep == ((struct nodeent *)0))
  352.         bpf_error("unknown decnet host name '%s'\n", name);
  353.  
  354.     memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
  355.     return(res);
  356. #else
  357.     bpf_error("decnet name support not included, '%s' cannot be translated\n",
  358.         name);
  359. #endif
  360. }
  361.